﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using KP_CommonLibrary.KP_CommonControls;
using KP_CommonLibrary.KP_ObjectReferences;
using KP_CommonLibrary.Logs;

namespace KP_CommonLibrary.KP_CoreUI
{
    public partial class KP_EditListItem : KP_CommonLibrary.KP_CommonControls.KP_FormSaveItem, IContainerDataSource
    {
        public bool InitDefault { get; set; }
        private KP_CommonLibrary.KP_Business.KP_BLListBase m_Business;
        [Browsable(false)]
        public KP_CommonLibrary.KP_Business.KP_BLListBase Business
        {
            get
            {
                if (m_Business == null)
                    CreateBusiness();
                return m_Business;
            }
            set
            {
                m_Business = value;
            }
        }
        protected CurrencyManager ParentBinding { get; set; }
        protected DataRow CurrentRow
        {
            get
            {
                if (bindingSource.DataSource != null)
                {
                    return (bindingSource.DataSource as DataRowView).Row;
                }
                return null;
            }
        }

        public event EventHandler FormStateChanged;
        public event FormStateChangingHandler FormStateChanging;
        private FormState fFormState = FormState.Unspecified;

        public FormState FormState
        {
            get { return fFormState; }
            set
            {
                if (fFormState != value)
                {
                    FormStateChangingArgs e = new FormStateChangingArgs(fFormState, value);
                    if (FormStateChanging != null)
                        FormStateChanging(this, e);
                    if (!e.Cancel)
                    {
                        fFormState = value;

                        switch (fFormState)
                        {
                            case FormState.Insert:
                                if (!String.IsNullOrEmpty(TitleInsert))
                                    Text = TitleInsert;
                                break;
                            case FormState.Update:
                                if (!String.IsNullOrEmpty(TitleUpdate))
                                    Text = TitleUpdate;
                                break;
                            default:
                                if (!String.IsNullOrEmpty(TitleNormal))
                                    Text = TitleNormal;
                                break;
                        }
                        if (FormStateChanged != null)
                            FormStateChanged(this, new EventArgs());
                        //kTestBindingController1.ContainerChangeState(value);
                    }
                }
            }

        }
        public KP_EditListItem()
        {
            InitializeComponent();
            if (DesignMode)
                return;
            Disposed += new EventHandler(KP_EditListItem_Disposed);
            LoadLayout();
        }
        [Category("KP Custom")]
        public virtual string TitleInsert { get; set; }
        [Category("KP Custom")]
        public virtual string TitleUpdate { get; set; }
        [Category("KP Custom")]
        public virtual string TitleNormal { get; set; }
        void KP_EditListItem_Disposed(object sender, EventArgs e)
        {
            bindingSource.DataSource = null;
            ParentBinding = null;
        }
        protected virtual void CreateBusiness()
        {
        }

        protected virtual void LoadLayout()
        {
        }
        public virtual void AddNew(CurrencyManager cm)
        {
            try
            {

                ParentBinding = cm;
                ParentBinding.AddNew();
                InitData((ParentBinding.Current as DataRowView).Row);
                LoadDependencyData();
                SetDataSource(ParentBinding.Current);
                FormState = FormState.Insert;
            }
            catch (Exception ex)
            {
                try
                {
                    if ((ParentBinding.Current as DataRowView).Row.RowState == DataRowState.Detached)
                        (ParentBinding.Current as DataRowView).Row.Delete();
                    else
                        ParentBinding.CancelCurrentEdit();
                }
                catch
                {
                }
                throw ex;
            }

        }
        public virtual void Edit(CurrencyManager cm)
        {
            ParentBinding = cm;
            LoadDependencyData();
            SetDataSource(cm.Current);
            FormState = FormState.Update;
        }
        public object GetDefaultValue4Column(Type t)
        {
            if (t == typeof(string))
                return string.Empty;
            if (t.IsValueType)
                return Activator.CreateInstance(t);
            return null;
        }

        public virtual void InitData(DataRow row)
        {
            if (InitDefault)
                foreach (DataColumn col in row.Table.Columns)
                    row[col] = GetDefaultValue4Column(col.DataType);
        }
        public virtual void LoadDependencyData()
        {
        }
        public virtual void CustomReadData(DataRow row)
        {
        }
        public virtual void CustomWriteData(DataRow row)
        {
            if (row.RowState == DataRowState.Unchanged)
                return;
            if (row.Table.Columns.Contains("Date0"))
                row["Date0"] = DateTime.Now.AddMilliseconds(KP_SYS_VARIABLE.M_DIFF_SERVER_TIME);
            if (row.Table.Columns.Contains("Client0"))
                row["Client0"] = KP_SYS_VARIABLE.M_CLIENT0;
            if (row.Table.Columns.Contains("User0"))
                row["User0"] = KP_OUser.User_Name;
        }
        public virtual bool ValidateAll()
        {
            if (CurrentRow == null)
            {
                KPMessageBox.Show("CurrentRow Is null", KP_SYS_VARIABLE.M_KEEPER_VER, KPMessageBoxButton.OK, KPMessageBoxIcon.Error);
                return false;
            }
            if (!Validate())
                return false;
            if (!ValidateChildren(ValidationConstraints.None))
                return false;
            String[] arrMess = kP_BindingController.ValidateRequirement();
            if (arrMess.Length > 0)
            {
                KPMessageBox.Show(String.Join("\n", arrMess), KP_SYS_VARIABLE.M_KEEPER_VER, KPMessageBoxButton.OK, KPMessageBoxIcon.Warning);
                return false;
            }
            return true;
        }

        protected virtual void SetDataSource(object obj)
        {
            bool performBinding = false;
            if (bindingSource.DataSource == null)
                performBinding = true;
            bindingSource.DataSource = obj;
            if (performBinding)
                kP_BindingController.BindingControl();
            CustomReadData(CurrentRow);
        }
        protected virtual void EndEdit()
        {
            try
            {
                CustomWriteData(CurrentRow);
                bindingSource.EndEdit();
            }
            catch (Exception e)
            {
                LogUtil.Logger.Fatal(GetType().ToString() + " Exception ", e);
                ParentBinding.EndCurrentEdit();
            }


        }

        public virtual void SaveAndClose()
        {
            
            try
            {
                Save(false);
            }
            catch (Exception ex)
            {
                KPMessageBox.Show(ex.Message, KP_SYS_VARIABLE.M_KEEPER_VER, KPMessageBoxButton.OK, KPMessageBoxIcon.Error);
                //Log vao log
            }
        }
        public virtual void SaveAndNew()
        {
           
            try
            {
                Save(true);

            }
            catch (Exception ex)
            {
                KPMessageBox.Show( ex.Message, KP_SYS_VARIABLE.M_KEEPER_VER, KPMessageBoxButton.OK, KPMessageBoxIcon.Error);
                //Log vao log
            }
        }

        protected virtual void Save(bool saveAndNew)
        {
            string state = "";
            try
            {


                state = "Kết thúc cập nhật\n";
                EndEdit();
                state = "Kiểm tra dữ liệu\n";
                if (ValidateAll())
                {
                    state = "Lưu thông tin\n";
                    if (FormState == FormState.Insert)
                    {
                        Business.Insert(CurrentRow);

                    }
                    else
                    {
                        Business.Update(CurrentRow);
                    }
                    CurrentRow.AcceptChanges();
                    FormState = FormState.Unspecified;
                    if (saveAndNew)
                    {
                        state = "Khởi tạo bản ghi mới\n";
                        AddNew(ParentBinding);
                    }
                    else
                        Close();
                }
            }
            catch (Exception ex)
            {
                throw new Exception(state + ex.Message);
            }
            
        }
        #region IContainerDataSource Members

        public virtual object GetSource(int index)
        {

            return bindingSource;

        }

        #endregion

        private void kpucSaveItem1_KPCloseClick(object sender, EventArgs e)
        {
            Close();
        }

        private void kpucSaveItem1_KPSaveAndCloseClick(object sender, EventArgs e)
        {
            SaveAndClose();
        }

        private void kpucSaveItem1_KPSaveAndNewClick(object sender, EventArgs e)
        {
            SaveAndNew();
        }

        private void KP_EditListItem_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                if (FormState == FormState.Insert || FormState == FormState.Update)
                {
                    if (CurrentRow.RowState == DataRowState.Detached)
                        CurrentRow.Delete();
                    else
                        if (FormState == FormState.Update && CurrentRow.RowState == DataRowState.Modified)
                            CurrentRow.RejectChanges();
                    //int pos=ParentBinding.Position;
                    ParentBinding.CancelCurrentEdit();
                    //if (FormState == FormState.Insert)
                    //    ParentBinding.RemoveAt(pos);
                }
            }
            catch (Exception ex)
            {
                KPMessageBox.Show(Text + " Closing error:" + ex.Message, KP_SYS_VARIABLE.M_KEEPER_VER, KPMessageBoxButton.OK, KPMessageBoxIcon.Error);
            }
        }

        private void KP_EditListItem_Load(object sender, EventArgs e)
        {

        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (DispatchCmdKey(ref msg, keyData))
                return true;
            return base.ProcessCmdKey(ref msg, keyData);
        }
        public virtual bool DispatchCmdKey(ref Message msg, Keys keyData)
        {
            //if(keyData
            switch (keyData)
            {
                case Keys.Control | Keys.S:
                    kpucSaveItem1_KPSaveAndCloseClick(this, new EventArgs());
                    return true;

                case Keys.Control | Keys.N:
                    kpucSaveItem1_KPSaveAndNewClick(this, new EventArgs());
                    return true;

                case Keys.Escape:
                    Close();
                    return true;

            }
            return false;
        }
    }
}
